﻿using System.Net;
using System.Text;
namespace System {
    /// <summary>
    /// 为WebClient增加 超时时间 Session 和 Cookie 的 WebClient。
    /// </summary>
    public class WebClientHelper:WebClient {
        private int _timeout;
        /// <summary>
        /// 超时时间(毫秒)
        /// </summary>
        public int Timeout {
            get {
                return _timeout;
            }
            set {
                _timeout = value;
            }
        }
        // Cookie 容器
        private CookieContainer cookieContainer;
        /// <summary>
        /// 创建一个新的 WebClient 实例。
        /// </summary>
        public WebClientHelper() {
            this.cookieContainer = new CookieContainer();
            this._timeout = 60000;
        }
        /// <summary>
        /// 创建一个新的 WebClient 实例。
        /// </summary>
        /// <param name="cookie">Cookie 容器</param>
        public WebClientHelper(CookieContainer cookies,int timeout = 60000) {
            this.cookieContainer = cookies;
            this._timeout = timeout;
        }
        /// <summary>
        /// Cookie 容器
        /// </summary>
        public CookieContainer Cookies {
            get { return this.cookieContainer; }
            set { this.cookieContainer = value; }
        }
        /// <summary>
        /// 返回带有 Cookie 的 HttpWebRequest。
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        protected override WebRequest GetWebRequest(Uri address) {
            var request = base.GetWebRequest(address);
            request.Timeout = this._timeout;
            if(request is HttpWebRequest) {
                HttpWebRequest httpRequest = request as HttpWebRequest;
                httpRequest.CookieContainer = cookieContainer;
            }
            return request;
        }
        #region 封装了PostData, GetSrc 和 GetFile 方法
        /// <summary>
        /// 向指定的 URL POST 数据，并返回页面
        /// </summary>
        /// <param name="uriString">POST URL</param>
        /// <param name="postString">POST 的 数据</param>
        /// <param name="postStringEncoding">POST 数据的 CharSet https://blog.csdn.net/gengyiping18/article/details/77620061</param>
        /// <param name="dataEncoding">页面的 CharSet</param>
        /// <returns>页面的源文件</returns>
        public string PostData(string uriString,string postString,string postStringEncoding = "utf-8",string dataEncoding = "utf-8") {
            try {
                // 将 Post 字符串转换成字节数组
                byte[] postData = Encoding.GetEncoding(postStringEncoding).GetBytes(postString);
                this.Headers.Add("Content-Type","application/x-www-form-urlencoded");
                // 上传数据，返回页面的字节数组
                byte[] responseData = this.UploadData(uriString,"POST",postData);
                // 将返回的将字节数组转换成字符串(HTML);
                string srcString = Encoding.GetEncoding(dataEncoding).GetString(responseData);
                srcString = srcString.Replace("\t","");
                srcString = srcString.Replace("\r","");
                srcString = srcString.Replace("\n","");
                return srcString;
            } catch(WebException we) {
                Logger.LogError("PostData:" + uriString + "?" + postString,we);
                return "error";
            }
        }
        /// <summary>
        /// 获得指定 URL 的源文件
        /// </summary>
        /// <param name="uriString">页面 URL</param>
        /// <param name="dataEncoding">页面的 CharSet</param>
        /// <returns>页面的源文件</returns>
        public string GetSrc(string uriString,string dataEncoding = "utf-8") {
            try {
                // 返回页面的字节数组
                byte[] responseData = this.DownloadData(uriString);
                // 将返回的将字节数组转换成字符串(HTML);
                string srcString = Encoding.GetEncoding(dataEncoding).GetString(responseData);
                srcString = srcString.Replace("\t","");
                srcString = srcString.Replace("\r","");
                srcString = srcString.Replace("\n","");
                return srcString;
            } catch(WebException we) {
                Logger.LogError("GetSrc:" + uriString,we);
                return "error";
            }
        }
        /// <summary>
        /// 从指定的 URL 下载文件到本地
        /// </summary>
        /// <param name="uriString">文件 URL</param>
        /// <param name="fileName">本地文件的完成路径</param>
        /// <returns></returns>
        public bool GetFile(string urlString,string fileName,out string msg) {
            try {
                this.DownloadFile(urlString,fileName);
                msg = string.Empty;
                return true;
            } catch(WebException we) {
                msg = we.Message;
                return false;
            }
        }
        #endregion
    }
}
